package com.zjdiepu.www.config;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;

import com.zjdiepu.www.security.server.core.Partners;
import com.zjdiepu.www.security.util.ResourcesUtil;

/**
 * 降低开发难度：暂时请求和响应共用一套
 * 类描述:对接:服务端 <br/>
 * 项目名称:zjdiepu-client <br/>
 * 类名称:ServerConfig <br/>
 * 创建人:xiongxiaotun <br/>
 * 创建时间:2017年8月15日 下午2:17:29 <br/>
 * 修改人:xiongxiaotun <br/>
 * 修改时间: 2017年8月15日 下午2:17:29 <br/>
 * 修改备注: <br/>
 * 
 * @version V1.0 <br/>
 */
public class ServerConfig {
	private static final Logger logger;
	static {
		logger = LoggerFactory.getLogger(ServerConfig.class);
		initServerConfig();
	}
	
	/**
	 * 碟普是否验签
	 */
	private static final String COMMON_SERVER_SIGN_SWITCH_PREFIX = "server.partner.sign.switch.";
	/**
	 * 碟普是否签名响应
	 */
	private static final String COMMON_SERVER_SIGN_RESPONSE_SWITCH_PREFIX = "server.partner.sign.response.switch.";
	/**
	 * 碟普签名类型
	 */
	private static final String COMMON_SERVER_SIGN_TYPE_PREFIX = "server.partner.sign.type.";
	/**
	 * 碟普签名属性名(key名称)
	 */
	private static final String COMMON_SERVER_SIGN_NAME_PREFIX = "server.partner.sign.name.";
	/**
	 * 碟普签名字符串参数名称
	 */
	private static final String COMMON_SERVER_SIGN_COVENANT_KEY_PREFIX = "server.partner.sign.covenant.key.";
	/**
	 * 碟普签名秘钥
	 */
	private static final String COMMON_SERVER_SIGN_SECRET_KEY_PREFIX = "server.partner.sign.secret.key.";
	/**
	 * 碟普算法盐值/秘钥:md5
	 */
	private static final String COMMON_SERVER_SIGN_MD5_SECRET_KEY_PREFIX = "server.partner.sign.md5.secret.key.";
	/**
	 * 碟普算法盐值/秘钥:jwt
	 */
	private static final String COMMON_SERVER_SIGN_JWT_SECRET_KEY_PREFIX = "server.partner.sign.jwt.secret.key.";
	/**
	 * 碟普算法盐值/秘钥:rsa
	 */
	//直接使用加密的秘钥
	private static final String COMMON_SERVER_SIGN_RSA_SECRET_KEY_PREFIX = "server.partner.sign.rsa.private.key.";
	
	
	/**
	 * 碟普数据加密类型
	 */
	private static final String COMMON_SERVER_ENCODE_TYPE_PREFIX = "server.partner.encode.type.";
	/**
	 * 碟普数据响应数据是否加密
	 */
	private static final String COMMON_SERVER_ENCODE_RESPONSE_PREFIX = "server.partner.encode.response.switch.";
	/**
	 * 碟普JWT加密私钥
	 */
	private static final String COMMON_SERVER_ENCODE_JWT_SECRET_KEY_PREFIX = "server.partner.encode.jwt.secret.key.";
	/**
	 * 碟普数据加密RSA公钥
	 */
	private static final String COMMON_SERVER_ENCODE_RSA_PRIVATE_KEY_PREFIX = "server.partner.encode.rsa.private.key.";
	
	
	/**
	 * 存储是否验签
	 */
	private static final String COMMON_SERVER_SIGN_SWITCH_SUBFIX = "-sign-switch";
	/**
	 * 存储是否签名响应
	 */
	private static final String COMMON_SERVER_SIGN_RESPONSE_SWITCH_SUBFIX = "-sign-response-switch";
	/**
	 * 存储是签名类型
	 */
	private static final String COMMON_SERVER_SIGN_TYPE_SUBFIX = "-sign-type";
	/**
	 * 存储是签名属性名(key名称)
	 */
	private static final String COMMON_SERVER_SIGN_NAME_SUBFIX = "-sign-name";
	/**
	 * 存储是签名字符串参数名称
	 */
	private static final String COMMON_SERVER_SIGN_COVENANT_KEY_SUBFIX = "-sign-covenant-key";
	/**
	 * 存储签名秘钥
	 */
	private static final String COMMON_SERVER_SIGN_SECRET_KEY_SUBFIX = "-sign-secret";
	/**
	 * 存储算法盐值/秘钥:md5
	 */
	private static final String COMMON_SERVER_SIGN_MD5_KEY_SUBFIX = "-sign-md5-secret";
	/**
	 * 存储算法盐值/秘钥:jwt
	 */
	private static final String COMMON_SERVER_SIGN_JWT_KEY_SUBFIX = "-sign-jwt-secret";
	/**
	 * 存储算法盐值/秘钥:rsa
	 */
	private static final String COMMON_SERVER_SIGN_RSA_KEY_SUBFIX = "-sign-rsa-public";
	
	
	/**
	 * 存储加密方式
	 */
	private static final String COMMON_SERVER_ENCODE_TYPE_SUBFIX = "-encode-type";
	/**
	 * 存储加密方式
	 */
	private static final String COMMON_SERVER_ENCODE_RESPONSE_SUBFIX = "-encode-response-switch";
	/**
	 * 存储jwt私钥
	 */
	private static final String COMMON_SERVER_ENCODE_JWT_KEY_SUBFIX = "-encode-jwt-secret";
	/**
	 * 存储RSA私钥
	 */
	private static final String COMMON_SERVER_ENCODE_RSA_KEY_SUBFIX = "-encode-rsa-private";
	
	/**
	 * 碟普
	 */
	private static Map<String, String> partnerSecretKeys;
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignSwitch  <br/>
	 * @Description 获取碟普是否验签<br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static boolean getPartnerSignSwitch(Partners partner) {
		return "true".equals(partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_SWITCH_SUBFIX));
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignResponseSwitch  <br/>
	 * @Description 获取碟普是否签名响应<br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static boolean getPartnerSignResponseSwitch(Partners partner) {
		return "true".equals(partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_RESPONSE_SWITCH_SUBFIX));
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignType  <br/>
	 * @Description 获取碟普签名类型<br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerSignType(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_TYPE_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignName  <br/>
	 * @Description 获取碟普签名签名属性名(key名称)<br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerSignName(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_NAME_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignCovenantKeyName  <br/>
	 * @Description 获取碟普签名字符串参数名称<br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerSignCovenantKeyName(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_COVENANT_KEY_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignSecretKey  <br/>
	 * @Description 获取碟普签名秘钥 <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerSignSecretKey(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_SECRET_KEY_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignMd5SecretKey  <br/>
	 * @Description 获取碟普算法盐值/秘钥 <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerSignMd5SecretKey(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_MD5_KEY_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignJwtSecretKey  <br/>
	 * @Description 获取碟普算法盐值/秘钥 <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerSignJwtSecretKey(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_JWT_KEY_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerSignRsaSecretKey  <br/>
	 * @Description 获取碟普算法盐值/秘钥 <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerSignRsaPublicKey(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_SIGN_RSA_KEY_SUBFIX);
	}
	
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerEncodeType  <br/>
	 * @Description 获取碟普加密方式 <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerEncodeType(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_ENCODE_TYPE_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerEncodeResponseSwitch  <br/>
	 * @Description 获取碟普响应数据是否加密 <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static boolean getPartnerEncodeResponseSwitch(Partners partner) {
		return "true".equals(partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_ENCODE_RESPONSE_SUBFIX));
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerRsaPublicKey  <br/>
	 * @Description 获取碟普数据加解密私钥:rsa <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerRsaPrivateKey(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_ENCODE_RSA_KEY_SUBFIX);
	}
	
	/**
	 * @author xiongxiaotun <br/>
	 * @Title getPartnerJwtSecretKey  <br/>
	 * @Description 获取碟普数据解密公钥:jwt <br/>
	 * @param partner
	 * @return
	 * @version V1.0  <br/>
	 */
	public static String getPartnerJwtSecretKey(Partners partner) {
		return partnerSecretKeys.get(partner.getCode() + COMMON_SERVER_ENCODE_JWT_KEY_SUBFIX);
	}
	

	public static Map<String, String> getPartnerSecretKeys() {
		return partnerSecretKeys;
	}
	
	// 获取
	public static void initServerConfig() {
		String location = "classpath*:/server-config.properties";
		InputStream resourceAsStream = null;
		try {
			Resource resource = ResourcesUtil.getResource(location);
			if(null == resource) {
				logger.error("加载服务端配置失败，没有找到匹配的资源文件...");
			}
			resourceAsStream = resource.getInputStream();
			logger.debug("加载服务端接口加密、签名开始...");
			Properties props = new Properties();
			props.load(resourceAsStream);
			Enumeration<Object> keys = props.keys();
			if(MapUtils.isEmpty(partnerSecretKeys)) {
				partnerSecretKeys = new HashMap<String, String>();
			}
			while(keys.hasMoreElements()) {
				String key = (String)keys.nextElement();
				if(StringUtils.isBlank(key)) {
					continue;
				}
				if(key.startsWith(COMMON_SERVER_SIGN_SWITCH_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_SWITCH_PREFIX.length());
					String signSwitch = partner + COMMON_SERVER_SIGN_SWITCH_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signSwitch))) {
						logger.warn("碟普是否验签重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signSwitch, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_RESPONSE_SWITCH_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_RESPONSE_SWITCH_PREFIX.length());
					String signSwitch = partner + COMMON_SERVER_SIGN_RESPONSE_SWITCH_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signSwitch))) {
						logger.warn("碟普是否签名响应重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signSwitch, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_TYPE_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_TYPE_PREFIX.length());
					String signSwitch = partner + COMMON_SERVER_SIGN_TYPE_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signSwitch))) {
						logger.warn("碟普签名类型重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signSwitch, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_NAME_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_NAME_PREFIX.length());
					String signSwitch = partner + COMMON_SERVER_SIGN_NAME_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signSwitch))) {
						logger.warn("碟普签名属性名(key名称)重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signSwitch, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_COVENANT_KEY_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_COVENANT_KEY_PREFIX.length());
					String signSwitch = partner + COMMON_SERVER_SIGN_COVENANT_KEY_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signSwitch))) {
						logger.warn("碟普签名字符串参数重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signSwitch, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_SECRET_KEY_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_SECRET_KEY_PREFIX.length());
					String signType = partner + COMMON_SERVER_SIGN_SECRET_KEY_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signType))) {
						logger.warn("碟普签名秘钥重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signType, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_MD5_SECRET_KEY_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_MD5_SECRET_KEY_PREFIX.length());
					String signType = partner + COMMON_SERVER_SIGN_MD5_KEY_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signType))) {
						logger.warn("碟普算法盐值/秘钥重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signType, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_JWT_SECRET_KEY_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_JWT_SECRET_KEY_PREFIX.length());
					String signType = partner + COMMON_SERVER_SIGN_JWT_KEY_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signType))) {
						logger.warn("碟普算法盐值/秘钥重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signType, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_SIGN_RSA_SECRET_KEY_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_SIGN_RSA_SECRET_KEY_PREFIX.length());
					String signType = partner + COMMON_SERVER_SIGN_RSA_KEY_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(signType))) {
						logger.warn("碟普算法盐值/秘钥重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(signType, props.getProperty(key));
				}
				
				
				if(key.startsWith(COMMON_SERVER_ENCODE_TYPE_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_ENCODE_TYPE_PREFIX.length());
					String encodeType = partner + COMMON_SERVER_ENCODE_TYPE_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(encodeType))) {
						logger.warn("碟普加密方式重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(encodeType, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_ENCODE_RESPONSE_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_ENCODE_RESPONSE_PREFIX.length());
					String encodeType = partner + COMMON_SERVER_ENCODE_RESPONSE_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(encodeType))) {
						logger.warn("碟普加密方式重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(encodeType, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_ENCODE_RSA_PRIVATE_KEY_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_ENCODE_RSA_PRIVATE_KEY_PREFIX.length());
					String rsaKey = partner + COMMON_SERVER_ENCODE_RSA_KEY_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(rsaKey))) {
						logger.warn("碟普RSA公钥重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(rsaKey, props.getProperty(key));
				}
				if(key.startsWith(COMMON_SERVER_ENCODE_JWT_SECRET_KEY_PREFIX)) {
					String partner = key.substring(COMMON_SERVER_ENCODE_JWT_SECRET_KEY_PREFIX.length());
					String jwtKey = partner + COMMON_SERVER_ENCODE_JWT_KEY_SUBFIX;
					if(StringUtils.isNotBlank(partnerSecretKeys.get(jwtKey))) {
						logger.warn("碟普算法盐值/秘钥重复. partner:{}." + partner);
					}
					partnerSecretKeys.put(jwtKey, props.getProperty(key));
				}
			}
			logger.debug("加载服务端接口加密、签名完成,项目个数:{}.",partnerSecretKeys.size());
		} catch (IOException e) {
			logger.debug("加载服务端接口加密、签名.异常栈:{}", e);
		} finally {
			if(null != resourceAsStream) {
				try {
					resourceAsStream.close();
				} catch (IOException e) {
					logger.error("加载客户端接口结束，关闭文件流异常:{}", e);
				}
			}
		}
	}
}
